package com.gigi.service.manual;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gigi.entity.FileEntity;
import com.gigi.entity.UserEntity;
import com.gigi.enums.ErrorCodeEnum;
import com.gigi.enums.YesOrNoEnum;
import com.gigi.mapper.generated.FileMapper;
import com.gigi.model.FileDO;
import com.gigi.model.ListFolderRequest;
import com.gigi.service.generated.FileService;
import com.gigi.service.generated.UserService;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class FileManageService {

    private final FileService fileService;
    private final FileMapper fileMapper;
    private final UserService userService;

    public FileManageService(FileService fileService, FileMapper fileMapper, UserService userService) {
        this.fileService = fileService;
        this.fileMapper = fileMapper;
        this.userService = userService;
    }

    /**
     * 列表接口
     *
     * @param request
     * @return
     */
    public MultiResponse<FileDO> list(ListFolderRequest request) {
        // 1、根据用户名模糊查询userId
        Long userId = null;
        if (StrUtil.isNotBlank(request.getUserName())) {
            LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<UserEntity>()
                    .like(UserEntity::getName, request.getUserName());
            UserEntity user = userService.getOne(wrapper, false);
            if (Objects.nonNull(user) && Objects.nonNull(user.getId())) {
                userId = user.getId();
            }
        }
        // 2、条件查询文件表
        LambdaQueryWrapper<FileEntity> wrapper = new LambdaQueryWrapper<FileEntity>()
                .eq(Objects.nonNull(request.getType()), FileEntity::getType, request.getType())
                .eq(Objects.nonNull(request.getUserId()), FileEntity::getUserId, request.getUserId())
                .eq(Objects.nonNull(request.getParentId()), FileEntity::getParentId, request.getParentId())
                .eq(Objects.nonNull(request.getState()), FileEntity::getState, request.getState())
                .like(StrUtil.isNotBlank(request.getFileName()), FileEntity::getName, request.getFileName())
                .eq(Objects.nonNull(userId), FileEntity::getUserId, userId)
                .orderByDesc(FileEntity::getId);
        List<FileEntity> list;
        int total = 0;
        if (YesOrNoEnum.YES.getCode().equals(request.getIfByPage())) {
            Page<FileEntity> page = new Page<>(request.getPageNum(), request.getPageSize());
            Page<FileEntity> fileEntityPage = fileMapper.selectPage(page, wrapper);
            list = fileEntityPage.getRecords();
            total = (int) fileEntityPage.getTotal();
        } else {
            list = fileService.list(wrapper);
        }
        if (CollUtil.isEmpty(list)) {
            return MultiResponse.ofWithoutTotal(Collections.emptyList());
        }
        // 3、封装返回结果
        List<FileDO> folderDOS = list.stream().map(e -> {
            FileDO folderDO = new FileDO();
            folderDO.setId(e.getId());
            folderDO.setName(e.getName());
            folderDO.setParentId(e.getParentId());
            folderDO.setType(e.getType());
            folderDO.setUrl(e.getUrl());
            folderDO.setState(e.getState());
            folderDO.setReason(e.getReason());
            folderDO.setTime(DateUtil.format(e.getTime(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
            folderDO.setUserName(userService.getById(e.getUserId()).getName());
            return folderDO;
        }).collect(Collectors.toList());
        return MultiResponse.of(folderDOS, total);
    }

    /**
     * 保存接口
     *
     * @param request
     * @return
     */
    public Response save(FileDO request) {
        if (ObjectUtil.isNull(request.getId())) {
            FileEntity target = buildTarget(request);
            boolean isSuccess = fileService.save(target);
            if (!isSuccess) {
                return Response.buildFailure(ErrorCodeEnum.SAVE_FAILED.getErrCode(), ErrorCodeEnum.SAVE_FAILED.getErrDesc());
            }
        } else {
            FileEntity entity = fileService.getById(request.getId());
            if (Objects.isNull(entity)) {
                return SingleResponse.buildFailure(ErrorCodeEnum.NO_DATA.getErrCode(), ErrorCodeEnum.NO_DATA.getErrDesc());
            }
            FileEntity target = buildTarget(request);
            target.setId(entity.getId());
            boolean isSuccess = fileService.updateById(target);
            if (!isSuccess) {
                return Response.buildFailure(ErrorCodeEnum.EDIT_FAILED.getErrCode(), ErrorCodeEnum.EDIT_FAILED.getErrDesc());
            }
        }
        return Response.buildSuccess();
    }

    /**
     * 创建target对象公共方法
     *
     * @param request
     * @return
     */
    private FileEntity buildTarget(FileDO request) {
        FileEntity target = new FileEntity();
        target.setName(request.getName());
        target.setUserId(request.getUserId());
        target.setTime(LocalDateTime.now());
        target.setState(request.getState());
        target.setReason(request.getReason());
        target.setType(request.getType());
        if (Objects.nonNull(request.getParentId())) {
            target.setParentId(request.getParentId());
        }
        if (StrUtil.isNotBlank(request.getUrl())) {
            target.setUrl(request.getUrl());
        }
        return target;
    }

    /**
     * 删除接口
     *
     * @param id
     * @return
     */
    public Response delete(Long id) {
        if (!fileService.removeById(id)) {
            return Response.buildFailure(ErrorCodeEnum.DELETE_FAILED.getErrCode(), ErrorCodeEnum.DELETE_FAILED.getErrDesc());
        }
        return Response.buildSuccess();
    }

}
